package com.company;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

/*
需求
1.有一张用户表，包含若干字段
2.方便对每个字段或字段组合进行检索，并打印出SQL
*/

/*
1.数据库和代码如何做映射？
2.考虑如何实现query方法
*/

/*
思路
每个类对应一张表
每个类中的属性对应表中的一个字段
给每个类和类中的属性加上自定义的注解
该注解命名为表名和字段名
在query函数中获取通过Class获取类或者属性的注解名 即表名和字段名
再通过反射创建类实例 调用get()方法获取对应的字段值 拼接出SQL语句
*/
public class Main {

    public static void main(String[] args) {

        //查询ID为10的用户
        Filter f1=new Filter();
        f1.setId(10);

        //查询用户为Lucy的用户
        Filter f2=new Filter();
        f2.setUserName("Lucy");
        f2.setAge(18);

        //查询邮箱为其中任意一个的用户
        Filter f3=new Filter();
        f3.setEmail("liu@sina.com");

        //调用query方法 返回对应的SQL语句
        String sql1=query(f1);
        String sql2=query(f2);
        String sql3=query(f3);

        System.out.println(sql1);
        System.out.println(sql2);
        System.out.println(sql3);

        Filter2 filter2=new Filter2();
        filter2.setAmount(10);
        filter2.setName("技术部");
        System.out.println(query(filter2));
    }

    private static String query(Object f) {
        StringBuilder sb=new StringBuilder();

        //1.通过获取到class 类类型
        Class c=f.getClass();

        //2.获取到Table名字
        boolean exists = c.isAnnotationPresent(Table.class); //判断该对象的类型是否存在注解@Table
        if(!exists) return null;

        Table t=(Table)c.getAnnotation(Table.class);
        String tableName=t.value();
        sb.append("select * from ").append(tableName).append(" where 1=1");

        //3.遍历所有字段
        Field[] fArray = c.getDeclaredFields();

        for(Field field:fArray) {
            //4.处理每个字段对应的SQL
            //4.1 拿到字段名

            boolean fExists=field.isAnnotationPresent(Column.class);
            if(!fExists) continue;

            Column column=field.getAnnotation(Column.class);
            String columnName=column.value();
            //4.2 拿到字段值

            Object fieldValue=null;
            String fieldName=field.getName();
            String getMethodName="get"+fieldName.substring(0,1).toUpperCase()+fieldName.substring(1); //获取get方法名 通过反射调用get方法 获取字段的值

            try {

                Method getMethod=c.getMethod(getMethodName);
                fieldValue=getMethod.invoke(f);

            } catch (Exception e) {
                e.printStackTrace();
            }
            //4.3 拼装SQL
            if(fieldValue==null||(fieldValue instanceof Integer && (Integer)fieldValue==0)) continue;

            sb.append(" and ").append(fieldName);
            if(fieldValue instanceof String)
            {
                sb.append("=").append("'").append(fieldValue).append("'");
            }
            else if(fieldValue instanceof Integer)
            {
                sb.append("=").append(fieldValue);
            }

        }

        return sb.toString();
    }
}
